/*****************************
 *@file: BlastBulletComp
 *@author: 陈吕唐
 *@desc: 爆炸子弹
 *@date: 2024-03-12	17:32
 *****************************/
import { Collider2D, Contact2DType, IPhysics2DContact, _decorator, warn } from 'cc';
import GameUtils from '../GameUtils';
import { MBoxGroup } from '../MBoxGroup';
import { BaseFightLogic } from '../core/BaseFightLogic';
import { PhysicsGroupEnum } from '../enum/PhysicsGroupEnum';
import { BaseBulletComp } from './BaseBulletComp';
const { ccclass, property } = _decorator;

@ccclass('BlastBulletComp')
export class BlastBulletComp extends BaseBulletComp {
    /****************************************************************************************************************
     *Readonly 常量
     ****************************************************************************************************************/
    /****************************************************************************************************************
     *Property 定义变量
     ****************************************************************************************************************/
    /**
     * 在爆炸范围内的战斗单位
     */
    protected sensorFightSet: Set<BaseFightLogic> = new Set();
    /***************************************************************
     *PropertyUI 引用的控件
     ***************************************************************/
    @property({ group: { name: 'Blast', id: '2' }, type: Collider2D, tooltip: `当前爆炸范围形状` })
    protected sensorCollider: Collider2D = null;
    /****************************************************************************************************************
     * Lifecycle 生命周期相关方法
     ****************************************************************************************************************/
    protected onEnable(): void {
        super.onEnable();
        let colliders = this.node.getComponents(Collider2D);
        if (!this.sensorCollider) {
            this.sensorCollider = colliders.find((c) => c.tag === MBoxGroup.ColliderTag.SENSOR);
        }

        this.addSensorListener(this.sensorCollider);
    }

    protected onDisable(): void {
        super.onDisable();
        if (this.sensorCollider) {
            this.sensorCollider.targetOff(this);
        }
    }

    public override unuse(): void {
        super.unuse();
        this.sensorFightSet.clear();
    }
    /****************************************************************************************************************
     * Public 公有方法
     ****************************************************************************************************************/
    /****************************************************************************************************************
     * private 私有方法
     ****************************************************************************************************************/

    protected override onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact): void {
        super.onBeginContact(selfCollider, otherCollider, contact);

        switch (otherCollider.group) {
            case PhysicsGroupEnum.BORDER:
                this.recycleBullet();
                break;
            default:
                break;
        }


        let fight = GameUtils.getFightByCollider(otherCollider);
        if (fight) {
            this.sensorFightSet.add(fight);
            this.sensorFightSet.forEach((item) => {
                item.hurt(this);
            });
            this.recycleBullet();
        }
    }

    /**
     * 进入感应范围时调用
     * @param selfCollider 
     * @param otherCollider 
     * @param contact 
     */
    protected onBeginSensorContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 只在两个碰撞体开始接触时被调用一次

        let fight = GameUtils.getFightByCollider(otherCollider);
        if (fight) {
            this.sensorFightSet.add(fight);
        }
    }

    /**
     * 退出感应范围时调用
     * @param selfCollider 
     * @param otherCollider 
     * @param contact 
     */
    protected onEndSensorContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 只在两个碰撞体结束接触时被调用一次

        let fight = GameUtils.getFightByCollider(otherCollider);
        if (fight) {
            this.sensorFightSet.delete(fight);
        }
    }

    /**
     * 添加感应范围监听
     * @param collider 
     * @returns 
     */
    protected addSensorListener(collider: Collider2D = this.bodyCollider) {
        if (!collider) {
            warn('collider is null');
            return;
        }

        if (!collider.hasEventListener(Contact2DType.BEGIN_CONTACT, this.onBeginSensorContact, this)) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginSensorContact, this);
        }
        if (!collider.hasEventListener(Contact2DType.END_CONTACT, this.onEndSensorContact, this)) {
            collider.on(Contact2DType.END_CONTACT, this.onEndSensorContact, this);
        }
    }
    /****************************************************************************************************************
     * Property Get && Set 属性的 get && set 函数
     ****************************************************************************************************************/

}


